package Game.Objects.Creatures;

import java.util.Random;

import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;

import GUI.GuiManager;
import Game.GameHelper;
import Game.Buff.DebuffPoison;
import Game.Items.Craft.GIRatMeat;
import Game.MapBlock.EMapBlockType;
import Game.Objects.GOPlayer;
import Game.Objects.GameObject;
import Game.Objects.ObjectManager;
import GameMath.GPoint;
import GameMath.GSize;
import Screens.MyScreens.GameScreen;

/** Rat creature class
 * @author Aikidos
 */
public class GOCRat extends GOCreature {

	/** Range of aggression */
	private int _rangeOfAggression = 2;
	
	/** Poisoned chance */
	private int _poisonedChance = 20;
	
	public GOCRat(ObjectManager objectManager) throws SlickException {
		super(objectManager, "Rat");
		
		setSprite(new Image("res/gfx/creatures/rat.png"));
		
		Type = EGameObjectType.Enemy;
		
		MaxHealth = 8;
		setHealth(MaxHealth);
		
		Magic = 3;
		Experience = 5;
		
		// Set default damage
		MinDamage = 1;
		MaxDamage = 1;
		
		// Add drop
		getInventory().addItem(new GIRatMeat(), 300);
	}
	
	@Override
	public void step() throws SlickException {
		super.step();
		
		boolean goToPlayer = false;
		boolean goToAlly = false;
		
		// Find player
		goToPlayer = stepFindPlayer();
		
		// Else find ally
		if (!goToPlayer) {
			goToAlly = stepFindAlly();
		}
		
		// Else go to random coordinate
		if (!goToPlayer && !goToAlly && (getWalkPath().size() == 0)) {
			stepGoToRandomCoord();
		}
		
		walk();
	}

	@Override
	public boolean onCollision(GameObject other, boolean moveOn) throws SlickException {
		if (other.isCreature())
		{
			GOCreature creature = (GOCreature) other;
			if (creature.Type == EGameObjectType.Ally)
			{
				if (moveOn) {
					attack(other);

					// Poisoned?
					if (GameHelper.getRandom().nextInt(1000) <= _poisonedChance) {
						DebuffPoison poison = new DebuffPoison(
								((GOCreature) other).getBuffManager());
					}
				}
				
				return false;
			}
		}
		else if (other.isPlayer())
		{
			if (moveOn) {
				attack(other);

				// Poisoned?
				if (GameHelper.getRandom().nextInt(1000) <= _poisonedChance) {
					DebuffPoison poison = new DebuffPoison(
							((GOPlayer) other).getBuffManager());
					
					// Show message
					GuiManager.getMessenger()
						.addMessage("[red]" + getName() + "[/red] poisoned [green]You[/green]");
				}
			}
			
			return false;
		}
		
		return true;
	}
	
	/** Find player and go to him
	 * @return true if player is found
	 */
	private boolean stepFindPlayer() {
		GOPlayer player = _objectManager.getPlayer();
		int distance = _objectManager.getLevel().getMap().getDistance(getCoord(), player.getCoord());
		if ((distance != -1) && (distance <= _rangeOfAggression)) {
			go(player.getCoord());
			return true;
		}
		
		return false;
	}
	
	/** Find ally mob and go to him
	 * @return true if ally mob is found
	 */
	private boolean stepFindAlly() {
		for (GameObject gameObject : _objectManager.getObjects()) {
			if (gameObject.isCreature() && (((GOCreature) gameObject).Type == EGameObjectType.Ally)) {
				int distance = _objectManager.getLevel().getMap().getDistance(getCoord(), gameObject.getCoord());
				if ((distance != -1) && (distance <= _rangeOfAggression)) {
					go(gameObject.getCoord());
					return true;
				}
			}
		}
		
		return false;
	}
	
	private void stepGoToRandomCoord() {
		// Get map size
		GSize mapSize = _objectManager.getLevel().getMap().getSize();

		// Go to random coordinates
		Random rnd = GameHelper.getRandom();

		GPoint p = new GPoint(rnd.nextInt(mapSize.width),
				rnd.nextInt(mapSize.height));

		while (_objectManager.getLevel().getMap().getBlocks()[p.x][p.y].Type != EMapBlockType.Floor)
			p = new GPoint(rnd.nextInt(mapSize.width),
					rnd.nextInt(mapSize.height));

		go(p);
	}

}
